home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
menus
/
toadmenu.zip
/
NEWEXEC.INC
< prev
next >
Wrap
Text File
|
1987-10-28
|
7KB
|
206 lines
(* from MARKET's Turbo archive, 9 Mar 87. Toad Hall
EXEC.PAS version 1.2
This file contains 2 functions for Turbo Pascal that allow you to
run other programs from within a Turbo program. The first function,
subProcess, actually calls up a different program using MS-DOS call
4BH, EXEC. The second function, GetComSpec, returns the path name
of the command interpreter, which is necessary to do certain
operations. There is also a main program that allows you to test the
functions.
----------------------------------------------------------------------
Version 1.1 works with DOS 2.0 and 2.1. Version 1.0 only worked
with DOS 3.0 due to a subtle bug in DOS 2.x.
- Bela Lubkin
Borland International Technical Support
CompuServe 71016,1573
----------------------------------------------------------------------
Version 1.2 corrects a compiling problem in the INLINE code area of
subProcess. The line:
INLINE ($8D/$96/ PathName+1 /
will always generate a ") required" at the + sign. Apparently
Turbo only allows displacements on location counter references
within the INLINE code (i.e. not on variable identifiers).
- James Tuksal
Burroughs Corporation
14115 Farmington Rd.
Livonia, Michigan
48154
----------------------------------------------------------------------
*)
TYPE
Str66 = STRING [66];
(*
Pass subProcess a string of the form:
'D:\FULL\PATH\NAME\OF\FILE.TYP parameter1 parameter2 ...'
For example,
'C:\SYSTEM\CHKDSK.COM'
'A:\WS.COM DOCUMENT.1'
'C:\DOS\LINK.EXE TEST;'
'C:\COMMAND.COM /C COPY *.* B:\BACKUP >FILESCOP.IED'
The fourth example shows several things. To do any of the
following, you must invoke the command processor and let it do the
work:
redirection
piping
path searching
searching for the extension of a program (.COM, .EXE, or .BAT)
batch files;
internal DOS commands
The name of the command processor file is stored in the DOS
environment. The function GetComSpec in this file returns the path
name of the command processor. Also note that you must use the /C
parameter or COMMAND will not work correctly. You can also call
COMMAND with no parameters. This will allow the user to use the DOS
prompt to run anything (as long as there is enough memory). To get
back to your program, he can type the command EXIT.
Actual example:
i := subProcess (GetComSpec+' /C COPY *.* B:\BACKUP >FILESCOP.IED');
The value returned is the result returned by DOS after the EXEC
call. The most common values are:
0: Success
1: Invalid function (should never happen with this routine)
2: File/path not found
8: Not enough memory to load program
10: Bad environment (greater than 32K)
11: Illegal .EXE file format
If you get any other result, consult an MS-DOS Technical Reference
manual.
VERY IMPORTANT NOTE: you MUST use the Options menu of Turbo Pascal
to restrict the amount of free dynamic memory used by your
program. Only the memory that is not used by the heap is
available for use by other programs.
*)
FUNCTION subProcess (CommandLine : Str255): INTEGER;
CONST
ssSave: INTEGER = 0;
SPSave: INTEGER = 0;
VAR
FCB1 : ARRAY [0..36] OF BYTE;
FCB2 : ARRAY [0..36] OF BYTE;
PathName : Str66;
CommandTail : Str255;
parmTable : RECORD
envseg : INTEGER;
comlin : ^INTEGER;
FCB1Pr : ^INTEGER;
FCB2Pr : ^INTEGER;
END;
BEGIN
IF POS (' ', CommandLine) = 0 THEN BEGIN
PathName := CommandLine + #0;
CommandTail := ^M;
END
ELSE BEGIN
PathName := COPY (CommandLine, 1, POS (' ', CommandLine)-1) + #0;
CommandTail := COPY (CommandLine, POS (' ', CommandLine), 255) + ^M;
END;
CommandTail [0] := PRED(CommandTail[0]);
WITH Regs Do BEGIN
FillChar (FCB1, SizeOf(FCB1), 0);
AX := $2901;
DS := Seg(CommandTail[1]);
SI := Ofs(CommandTail[1]);
ES := Seg(FCB1);
DI := Ofs(FCB1);
MSDOS (Regs); { Create FCB 1 }
FillChar (FCB2, SizeOf(FCB2), 0);
AX := $2901;
ES := Seg(FCB2);
DI := Ofs(FCB2);
MSDOS (Regs); { Create FCB 2 }
ES := CSeg;
BX := SSEG - CSEG + MEMW[CSEG:MEMW[CSEG:$0101] + $112];
AH := $4A;
MSDOS (Regs); { Deallocate unused memory }
WITH parmTable DO BEGIN
envseg := MEMW[CSEG:$002C];
comlin := ADDR(CommandTail);
FCB1Pr := ADDR(FCB1);
FCB2Pr := ADDR(FCB2);
END;
INLINE (
$BF/$01/$00/ {+MOV DI,0001h }
$8D/$93/PathName/ {>LEA DX,[BP+DI+DS:PathName] }
$8D/$9E/parmTable/ { LEA BX,[BP+DS:parmTable] }
$B8/$00/$4B/ { MOV AX,4B00h }
$1E/ { PUSH DS }
$55/ { PUSH BP }
$16/ { PUSH SS }
$1F/ { POP DS }
$16/ { PUSH SS }
$07/ { POP ES }
$2E/$8C/$16/SSSave/ { MOV CS:ssSave,SS }
$2E/$89/$26/SPSave/ { MOV CS:SPSave,SP }
$FA/ { CLI }
$CD/$21/ { INT 21h }
$FA/ { CLI }
$2E/$8B/$26/SPSave/ { MOV SP,CS:SPSave }
$2E/$8E/$16/SSSave/ { MOV SS,CS:ssSave }
$FB/ { STI }
$9C/ { PUSHF }
$BF/$12/$00/ {+MOV DI,0012h }
$3E/$8F/$83/Regs/ {>POP [BP+DI+DS:Regs] }
$3E/$89/$86/Regs/ { MOV [BP+DS:Regs],AX }
$5D/ { POP BP }
$1F); { POP DS }
{ + Line added to correct compile problem in 1.1 }
{ > Line modified to correct compile problem in 1.1 }
{ The messing around with SS and SP is necessary because under DOS 2.x }
{ after returning from an EXEC call, ALL registers are destroyed }
{ except CS and IP! I wish I'd known that before I released this }
{ package the first time... }
IF (Flags AND 1) <> 0 THEN subProcess := AX
ELSE subProcess := 0;
END;
END; { of subProcess }
FUNCTION GetComSpec : Str66;
TYPE
Env = ARRAY [0..32767] OF CHAR;
VAR
EPtr : ^Env;
EStr : Str255;
Done : BOOLEAN;
i : INTEGER;
BEGIN
EPtr := PTR (MEMW [CSEG:$002C],0);
i := 0;
Done := FALSE;
EStr := '';
REPEAT
IF EPtr^[i] = #0 THEN BEGIN
IF EPtr^[SUCC(i)] = #0 THEN Done := TRUE;
IF COPY (EStr, 1, 8) = 'COMSPEC=' THEN BEGIN
GetComSpec := COPY (EStr, 9, 100);
Done := TRUE;
END;
EStr := '';
END
ELSE EStr := EStr + EPtr^[i];
i := SUCC(i);
UNTIL Done;
END; { of GetComSpec }